package com.atguigu.tingshu.user.service.impl;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.config.WxMaConfig;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.IdUtil;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.rabbit.constant.MqConst;
import com.atguigu.tingshu.common.rabbit.service.RabbitService;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.model.user.UserInfo;
import com.atguigu.tingshu.model.user.UserPaidAlbum;
import com.atguigu.tingshu.model.user.UserPaidTrack;
import com.atguigu.tingshu.user.mapper.UserInfoMapper;
import com.atguigu.tingshu.user.mapper.UserPaidAlbumMapper;
import com.atguigu.tingshu.user.mapper.UserPaidTrackMapper;
import com.atguigu.tingshu.user.service.UserInfoService;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {

	@Autowired
	private UserInfoMapper userInfoMapper;
	@Autowired
	private WxMaService wxMaService;
	@Autowired
	private WxMaConfig wxMaConfig;
	@Autowired
	private RedisTemplate redisTemplate;
	@Autowired
	private RabbitService rabbitService;

	@Override
	@SneakyThrows
	public Map<String, String> wxLogin(String code) {

		WxMaJscode2SessionResult sessionInfo = wxMaService.getUserService().getSessionInfo(code);

		if (sessionInfo != null) {
			String sessionKey = sessionInfo.getSessionKey();
			String openid = sessionInfo.getOpenid();
			String unionid = sessionInfo.getUnionid();

			LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getWxOpenId, openid);
			UserInfo user = userInfoMapper.selectOne(queryWrapper);

			//	判断是否为首次登陆,首次登陆需要隐式注册并初始化账户
			//	登陆过才会往库里存,库中才会有数据
			if (user == null) {
				user = new UserInfo();
				user.setWxOpenId(openid);
				user.setNickname("书友" + IdUtil.getSnowflakeNextIdStr());
				user.setAvatarUrl("http://192.168.254.156:9000/glsx/2025-06-15/2fd1dfc7-b2c3-41b8-9891-3a4d1c0db12b.jpg");
				userInfoMapper.insert(user);

				rabbitService.sendMessage(MqConst.EXCHANGE_USER,MqConst.ROUTING_USER_REGISTER,user.getId());

			}

			String token = IdUtil.getSnowflakeNextIdStr();
			String loginKey = RedisConstant.USER_LOGIN_KEY_PREFIX + token;
			UserInfoVo userInfoVo = BeanUtil.copyProperties(user, UserInfoVo.class);
			redisTemplate.opsForValue().set(loginKey, userInfoVo, RedisConstant.USER_LOGIN_KEY_TIMEOUT, TimeUnit.SECONDS);


			HashMap<String, String> tokenMap = new HashMap<>();
			tokenMap.put("token", token);
			return tokenMap;
		}
		return null;
	}

	@Override
	public UserInfoVo getUserInfo(String token) {
		String loginKey = RedisConstant.USER_LOGIN_KEY_PREFIX + token;
		UserInfoVo userInfoVo = (UserInfoVo) redisTemplate.opsForValue().get(loginKey);
		return userInfoVo;
	}

	@Override
	public void updateUser(UserInfoVo userInfoVo, Long userId, String token) {

		UserInfo userInfo = userInfoMapper.selectById(userId);
		userInfo.setAvatarUrl(userInfoVo.getAvatarUrl());
		userInfo.setNickname(userInfoVo.getNickname());
		userInfoMapper.updateById(userInfo);

		userInfoVo = BeanUtil.copyProperties(userInfo, UserInfoVo.class);
		String loginKey = RedisConstant.USER_LOGIN_KEY_PREFIX + token;
		redisTemplate.opsForValue().set(loginKey,userInfoVo,RedisConstant.USER_LOGIN_KEY_TIMEOUT,TimeUnit.SECONDS);

	}

	@Override
	public UserInfoVo getUserInfoVo(Long userId) {

		UserInfo userInfo = userInfoMapper.selectById(userId);
		UserInfoVo userInfoVo = BeanUtil.copyProperties(userInfo, UserInfoVo.class);
		return userInfoVo;

	}

	@Autowired
	private UserPaidAlbumMapper userPaidAlbumMapper;
	@Autowired
	private UserPaidTrackMapper userPaidTrackMapper;

	@Override
	public Map<Long, Integer> userIsPaidTrack(Long userId, Long albumId, List<Long> waitCheckIds) {

		LambdaQueryWrapper<UserPaidAlbum> paidAlbumQueryWrapper = new LambdaQueryWrapper<>();
		paidAlbumQueryWrapper.eq(UserPaidAlbum::getUserId,userId);
		paidAlbumQueryWrapper.eq(UserPaidAlbum::getAlbumId,albumId);

		Long count = userPaidAlbumMapper.selectCount(paidAlbumQueryWrapper);
		if (count > 0) {

			Map<Long, Integer> payResultMap = waitCheckIds.stream()
					.collect(Collectors.toMap(waitCheckId -> waitCheckId, waitCheckId -> 1));

			return payResultMap;
		}

		LambdaQueryWrapper<UserPaidTrack> paidTrackQueryWrapper = new LambdaQueryWrapper<>();
		paidTrackQueryWrapper.eq(UserPaidTrack::getUserId,userId);
		paidTrackQueryWrapper.eq(UserPaidTrack::getAlbumId,albumId);

		List<UserPaidTrack> userPaidTracks = userPaidTrackMapper.selectList(paidTrackQueryWrapper);

		if (CollectionUtil.isEmpty(userPaidTracks)) {
			Map<Long, Integer> payResultMap = waitCheckIds.stream()
					.collect(Collectors.toMap(waitCheckId -> waitCheckId, waitCheckId -> 0));

			return payResultMap;
		}

		List<Long> payTracks = userPaidTracks.stream()
				.map(userPaidTrack -> userPaidTrack.getTrackId()).collect(Collectors.toList());

		Map<Long, Integer> payResultMap = waitCheckIds.stream()
				.collect(Collectors.toMap(waitCheckId -> waitCheckId, waitCheckId -> {
					if (payTracks.contains(waitCheckId)) {
						return 1;
					}else {
						return 0;
					}
				}));


		return payResultMap;
	}


}
